/*
 * 
 */
package com.wowocai.btchina.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;

import com.wowocai.btchina.utils.ip.GeoIpUtil;

/**
 * @author 刘建成
 */
public class BaseController implements InitializingBean {

    @Autowired
    private MessageSource messageSource;

    private static Logger logger = LoggerFactory.getLogger(BaseController.class);

    private static final String LOCAL_IP_V4 = "127.0.0.1";

    private static final String LOCAL_IP_V6 = "0:0:0:0:0:0:0:1";

    private static final String DEFAULT_COUNTRY = "US";

    private static final String SESSION_ADS_COUNTRY = "adcountry";

    private static final List<String> AD_COUNTRIES = new ArrayList<String>(10);

    static {
        AD_COUNTRIES.add(DEFAULT_COUNTRY);
        AD_COUNTRIES.add("CN");
        AD_COUNTRIES.add("GB");
        AD_COUNTRIES.add("DE");
        AD_COUNTRIES.add("FR");
        AD_COUNTRIES.add("JP");
        AD_COUNTRIES.add("ES");
        AD_COUNTRIES.add("IN");
        AD_COUNTRIES.add("BR");
        AD_COUNTRIES.add("MX");
    }

    /**
     * 获取国际化参数
     * <br/>
     * 
     * @author 刘建成
     * @param request
     * @param key
     * @return
     */
    public String getLocalMessage(HttpServletRequest request, String key, Object[] args) {
        Locale locale = RequestContextUtils.getLocale(request);
        String msg = messageSource.getMessage(key, args, locale);
        return msg;
    }

    /**
     * 根据IP得到国家编码
     * <br/>
     * 
     * @author 刘建成
     * @param request
     * @return
     */
    public String getClientCountry(HttpServletRequest request) {
        String ip = this.getClientIP(request);
        if (ip == null) {
            return DEFAULT_COUNTRY;
        }
        String country = GeoIpUtil.getCcodeByIP(ip);
        if (country == null) {
            return DEFAULT_COUNTRY;
        }
        return country;
    }

    /**
     * 根据IP得到广告所属的国家编码
     * <br/>
     * 
     * @author 刘建成
     * @param request
     * @return
     */

    public String getClientAdCountry(HttpServletRequest request) {
        // TODO 根据IP取广告AWS会报错,所以固定为US
        String adsCountry = (String) request.getSession().getAttribute(SESSION_ADS_COUNTRY);
        if (adsCountry != null) {
            return adsCountry;
        } else {
            request.getSession().setAttribute(SESSION_ADS_COUNTRY, DEFAULT_COUNTRY);
        }
        return DEFAULT_COUNTRY;
        // adsCountry = this.getClientCountry(request);
        // if (adsCountry == null || !AD_COUNTRIES.contains(adsCountry)) {
        // adsCountry = DEFAULT_COUNTRY;
        // }
        // request.getSession().setAttribute(SESSION_ADS_COUNTRY, adsCountry);
        // return DEFAULT_COUNTRY;
    }

    /**
     * 获取客户端IP地址
     * 
     * @param request
     * @return
     */
    public String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr().equals(LOCAL_IP_V6) ? LOCAL_IP_V4 : request.getRemoteAddr();
        }
        if (ip == null) {
            logger.error("没有获取到IP");
            return null;
        }
        // IP地址是多个时只取1个
        String[] s = ip.split(",");
        if (s.length > 1) {
            // logger.info("检测到有多个IP：{}", ip);
            String ip_ = s[0].trim();
            // 有可能会出现使用虚拟机，这种情况就取不到真实IP，s[0]取到的是127.0.0.1，所以要取s[1]
            if (LOCAL_IP_V4.equals(ip_) || LOCAL_IP_V6.equals(ip_)) {
                return s[1].trim();
            }
            return ip_;
        } else {
            return ip.trim();
        }
    }

    /**
     * TODO The function of this method is described here - Optional.
     * 
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    @Override
    public void afterPropertiesSet() throws Exception {

    }

    public void putLocale(HttpServletRequest request) {
        Locale locale = (Locale) request.getSession().getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
        if (locale == null) {
            locale = LocaleContextHolder.getLocale();
        }
        String locale_ = locale.getLanguage();
        request.getSession().setAttribute("locale", locale_);
    }

    /**
     * 修改语言
     * <br/>
     * 
     * @author 刘建成
     * @param request
     * @param lang
     * @return
     */
    public Locale changeLanguage(HttpServletRequest request, String lang) {
        Locale tmp = (Locale) request.getSession().getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
        if (StringUtils.isBlank(lang)) {
            return tmp;
        }
        Locale locale = null;
        switch (lang.trim().toLowerCase()) {
            case "en":
                locale = Locale.ENGLISH;
                break;
            case "ar":
                locale = new Locale("ar", "");
                break;
            case "de":
                locale = Locale.GERMAN;
                break;
            case "es":
                locale = new Locale("es", "");
                break;
            case "fr":
                locale = Locale.FRENCH;
                break;
            case "it":
                locale = Locale.ITALIAN;
                break;
            case "pt":
                locale = new Locale("pt", "");
                break;
            case "ru":
                locale = new Locale("ru", "");
                break;
            case "zh":
                locale = Locale.CHINESE;
                break;
            case "ja":
                locale = Locale.JAPANESE;
                break;
            case "ko":
                locale = Locale.KOREAN;
                break;
            case "in":
                locale = new Locale("in", "");
                break;
            case "hi":
                locale = new Locale("hi", "");
                break;
            case "no":
                locale = new Locale("no", "");
                break;
            case "sv":
                locale = new Locale("sv", "");
                break;
            case "fi":
                locale = new Locale("fi", "");
                break;
            case "ur":
                locale = new Locale("ur", "");
                break;
            case "da":
                locale = new Locale("da", "");
                break;
            default:
                locale = Locale.ENGLISH;
                break;
        }

        // 修改语言
        if (tmp != null && tmp.equals(locale)) {
            return tmp;
        } else {
            request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale);
            return locale;
        }
    }
}
